package com.huashi.dealer.modular.business.role.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.huashi.dealer.commonEntity.StoreAccess;
import com.huashi.dealer.commonEntity.StoreRole;
import com.huashi.dealer.commonEntity.StoreRoleAccess;
import com.huashi.dealer.core.exception.ServiceException;
import com.huashi.dealer.modular.business.role.param.*;
import com.huashi.dealer.modular.business.role.service.StoreRoleService;
import com.huashi.dealer.modular.business.user.mapper.StoreAccessMapper;
import com.huashi.dealer.modular.business.user.mapper.StoreRoleAccessMapper;
import com.huashi.dealer.modular.business.user.mapper.StoreRoleMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 角色服务实现类
 *
 * @author 谭陈强
 * @since 2025-01-27
 */
@Slf4j
@Service
public class StoreRoleServiceImpl implements StoreRoleService {

    @Autowired
    private StoreRoleMapper storeRoleMapper;

    @Autowired
    private StoreAccessMapper storeAccessMapper;

    @Autowired
    private StoreRoleAccessMapper storeRoleAccessMapper;

    @Override
    public List<StoreRoleVo> getRoleList(StoreRoleListParam param) {
        // 查询所有角色
        List<StoreRole> roles = getAllRoles(param);

        // 格式化为树形结构
        return formatTreeData(roles);
    }

    @Override
    public StoreRoleDetailVo getRoleDetail(Long roleId) {
        // 获取角色信息
        StoreRole role = storeRoleMapper.selectById(roleId);
        if (role == null) {
            throw new ServiceException("角色不存在");
        }

        StoreRoleDetailVo result = new StoreRoleDetailVo();

        // 转换角色信息
        StoreRoleVo roleVo = convertToVo(role);
        result.setRole(roleVo);

        // 获取权限列表
        List<StoreAccess> allAccess = getAllAccess();
        List<StoreAccessVo> accessList = formatAccessTreeData(allAccess);
        result.setAccessList(accessList);

        // 获取角色列表（用于上级角色选择）
        List<StoreRole> allRoles = storeRoleMapper.selectList(null);
        List<StoreRoleVo> roleList = formatTreeData(allRoles);
        result.setRoleList(roleList);

        // 获取已分配的权限ID
        List<Long> assignedAccessIds = storeRoleAccessMapper.selectAccessIdsByRoleIds(Arrays.asList(roleId));
        result.setAssignedAccessIds(assignedAccessIds);

        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addRole(StoreRoleParam param) {
        // 验证权限不能为空
        if (CollectionUtils.isEmpty(param.getAccess())) {
            throw new ServiceException("请选择权限");
        }

        // 验证上级角色
        if (param.getParentId() != null && param.getParentId() > 0) {
            StoreRole parentRole = storeRoleMapper.selectById(param.getParentId());
            if (parentRole == null) {
                throw new ServiceException("上级角色不存在");
            }
        }

        try {
            // 创建角色
            StoreRole role = new StoreRole();
            role.setRoleName(param.getRoleName());
            role.setParentId(param.getParentId() != null ? param.getParentId() : 0L);
            role.setSort(param.getSort() != null ? param.getSort() : 100);
            role.setWxappId(getCurrentWxappId());
            role.setCreateTime(System.currentTimeMillis() / 1000);
            role.setUpdateTime(System.currentTimeMillis() / 1000);

            storeRoleMapper.insert(role);

            // 添加角色权限关系
            addRoleAccessRelations(role.getRoleId(), param.getAccess());

            return true;
        } catch (Exception e) {
            log.error("添加角色失败", e);
            throw new ServiceException("添加角色失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateRole(Long roleId, StoreRoleParam param) {
        // 验证角色存在
        StoreRole existingRole = storeRoleMapper.selectById(roleId);
        if (existingRole == null) {
            throw new ServiceException("角色不存在");
        }

        // 验证权限不能为空
        if (CollectionUtils.isEmpty(param.getAccess())) {
            throw new ServiceException("请选择权限");
        }

        // 验证上级角色不能设置为自己或自己的子角色
        if (param.getParentId() != null && param.getParentId() > 0) {
            if (param.getParentId().equals(roleId)) {
                throw new ServiceException("上级角色不能设置为自己");
            }

            // 检查是否是子角色
            List<Long> childRoleIds = getChildRoleIds(roleId);
            if (childRoleIds.contains(param.getParentId())) {
                throw new ServiceException("上级角色不能设置为子角色");
            }
        }

        try {
            // 更新角色信息
            existingRole.setRoleName(param.getRoleName());
            existingRole.setParentId(param.getParentId() != null ? param.getParentId() : 0L);
            existingRole.setSort(param.getSort() != null ? param.getSort() : 100);
            existingRole.setUpdateTime(System.currentTimeMillis() / 1000);

            storeRoleMapper.updateById(existingRole);

            // 更新角色权限关系
            updateRoleAccessRelations(roleId, param.getAccess());

            return true;
        } catch (Exception e) {
            log.error("更新角色失败", e);
            throw new ServiceException("更新角色失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteRole(Long roleId) {
        // 验证角色存在
        StoreRole role = storeRoleMapper.selectById(roleId);
        if (role == null) {
            throw new ServiceException("角色不存在");
        }

        // 检查是否有子角色
        List<StoreRole> childRoles = storeRoleMapper.selectList(
            new LambdaQueryWrapper<StoreRole>()
                .eq(StoreRole::getParentId, roleId)
        );

        if (!CollectionUtils.isEmpty(childRoles)) {
            throw new ServiceException("当前角色下存在子角色，请先删除子角色");
        }

        try {
            // 删除角色权限关系
            storeRoleAccessMapper.deleteByRoleId(roleId);

            // 删除角色
            return storeRoleMapper.deleteById(roleId) > 0;
        } catch (Exception e) {
            log.error("删除角色失败", e);
            throw new ServiceException("删除角色失败：" + e.getMessage());
        }
    }

    @Override
    public String getAccessTreeJson(Long roleId) {
        List<StoreAccess> allAccess = getAllAccess();
        List<Long> assignedAccessIds = null;

        if (roleId != null && roleId > 0) {
            assignedAccessIds = storeRoleAccessMapper.selectAccessIdsByRoleIds(Arrays.asList(roleId));
        }

        return buildJsTreeJson(allAccess, assignedAccessIds);
    }

    @Override
    public List<StoreAccessVo> getAccessList() {
        // 获取所有权限（包括子权限）
        List<StoreAccess> allAccess = getAllAccess();
        return formatAccessTreeData(allAccess);
    }

    /**
     * 获取所有角色
     */
    private List<StoreRole> getAllRoles(StoreRoleListParam param) {
        LambdaQueryWrapper<StoreRole> wrapper = new LambdaQueryWrapper<>();

        // 按角色ID过滤
        if (param != null && param.getRoleIds() != null && param.getRoleIds().length > 0) {
            wrapper.in(StoreRole::getRoleId, Arrays.asList(param.getRoleIds()));
        }

        // 按名称搜索
        if (param != null && StringUtils.hasText(param.getSearch())) {
            wrapper.like(StoreRole::getRoleName, param.getSearch());
        }

        // 按排序和创建时间排序
        wrapper.orderByAsc(StoreRole::getSort)
               .orderByDesc(StoreRole::getCreateTime);

        return storeRoleMapper.selectList(wrapper);
    }

    /**
     * 获取所有权限
     */
    private List<StoreAccess> getAllAccess() {
        return storeAccessMapper.selectList(
            new LambdaQueryWrapper<StoreAccess>()
                .orderByAsc(StoreAccess::getSort)
                .orderByAsc(StoreAccess::getAccessId)
        );
    }

    /**
     * 格式化角色树形数据
     */
    private List<StoreRoleVo> formatTreeData(List<StoreRole> roles) {
        List<StoreRoleVo> result = new ArrayList<>();
        Map<Long, List<StoreRole>> roleMap = roles.stream()
            .collect(Collectors.groupingBy(StoreRole::getParentId));

        formatTreeRecursive(result, roleMap, 0L, 1);

        return result;
    }

    /**
     * 递归格式化树形数据
     */
    private void formatTreeRecursive(List<StoreRoleVo> result, Map<Long, List<StoreRole>> roleMap,
                                   Long parentId, int deep) {
        List<StoreRole> children = roleMap.get(parentId);
        if (CollectionUtils.isEmpty(children)) {
            return;
        }

        for (StoreRole role : children) {
            StoreRoleVo vo = convertToVo(role);
            vo.setDeep(deep);
            vo.setRoleNameH1(getHtmlPrefix(deep) + role.getRoleName());

            result.add(vo);

            // 递归处理子角色
            formatTreeRecursive(result, roleMap, role.getRoleId(), deep + 1);
        }
    }

    /**
     * 格式化权限树形数据（返回真正的树形结构）
     */
    private List<StoreAccessVo> formatAccessTreeData(List<StoreAccess> accesses) {
        Map<Long, List<StoreAccess>> accessMap = accesses.stream()
            .collect(Collectors.groupingBy(StoreAccess::getParentId));

        return buildAccessTreeRecursive(accessMap, 0L, 1);
    }

    /**
     * 递归构建权限树形结构
     */
    private List<StoreAccessVo> buildAccessTreeRecursive(Map<Long, List<StoreAccess>> accessMap,
                                                         Long parentId, int deep) {
        List<StoreAccess> children = accessMap.get(parentId);
        if (CollectionUtils.isEmpty(children)) {
            return new ArrayList<>();
        }

        List<StoreAccessVo> result = new ArrayList<>();

        for (StoreAccess access : children) {
            StoreAccessVo vo = new StoreAccessVo();
            vo.setAccessId(access.getAccessId());
            vo.setName(access.getName());
            vo.setParentId(access.getParentId());
            vo.setSort(access.getSort());
            vo.setCreateTime(access.getCreateTime());
            vo.setUpdateTime(access.getUpdateTime());
            vo.setDeep(deep);
            vo.setNameH1(getHtmlPrefix(deep) + access.getName());

            // 递归构建子权限
            List<StoreAccessVo> childVos = buildAccessTreeRecursive(accessMap, access.getAccessId(), deep + 1);
            vo.setChildren(childVos);
            vo.setHasChildren(!CollectionUtils.isEmpty(childVos));

            result.add(vo);
        }

        return result;
    }

    /**
     * 转换StoreRole为StoreRoleVo
     */
    private StoreRoleVo convertToVo(StoreRole role) {
        StoreRoleVo vo = new StoreRoleVo();
        vo.setRoleId(role.getRoleId());
        vo.setRoleName(role.getRoleName());
        vo.setParentId(role.getParentId());
        vo.setSort(role.getSort());
        vo.setWxappId(role.getWxappId());
        vo.setCreateTime(role.getCreateTime());
        vo.setUpdateTime(role.getUpdateTime());
        return vo;
    }

    /**
     * 获取HTML前缀
     */
    private String getHtmlPrefix(int deep) {
        if (deep <= 1) {
            return "";
        }

        StringBuilder prefix = new StringBuilder();
        for (int i = 1; i < deep; i++) {
            prefix.append("&nbsp;&nbsp;&nbsp;├ ");
        }
        prefix.append("&nbsp;");
        return prefix.toString();
    }

    /**
     * 添加角色权限关系
     */
    private void addRoleAccessRelations(Long roleId, List<Long> accessIds) {
        if (CollectionUtils.isEmpty(accessIds)) {
            return;
        }

        // 批量插入角色权限关系
        storeRoleAccessMapper.batchInsert(roleId, accessIds);
    }

    /**
     * 更新角色权限关系
     */
    private void updateRoleAccessRelations(Long roleId, List<Long> newAccessIds) {
        // 获取现有的权限ID
        List<Long> existingAccessIds = storeRoleAccessMapper.selectAccessIdsByRoleIds(Arrays.asList(roleId));

        // 找出需要删除的权限
        List<Long> toDelete = existingAccessIds.stream()
            .filter(id -> !newAccessIds.contains(id))
            .collect(Collectors.toList());

        // 找出需要添加的权限
        List<Long> toAdd = newAccessIds.stream()
            .filter(id -> !existingAccessIds.contains(id))
            .collect(Collectors.toList());

        // 删除不需要的权限关系
        if (!CollectionUtils.isEmpty(toDelete)) {
            QueryWrapper<StoreRoleAccess> deleteWrapper = new QueryWrapper<>();
            deleteWrapper.eq("role_id", roleId)
                        .in("access_id", toDelete);
            storeRoleAccessMapper.delete(deleteWrapper);
        }

        // 添加新的权限关系
        if (!CollectionUtils.isEmpty(toAdd)) {
            addRoleAccessRelations(roleId, toAdd);
        }
    }

    /**
     * 获取子角色ID列表
     */
    private List<Long> getChildRoleIds(Long parentId) {
        List<Long> childIds = new ArrayList<>();
        getChildRoleIdsRecursive(childIds, parentId);
        return childIds;
    }

    /**
     * 递归获取子角色ID
     */
    private void getChildRoleIdsRecursive(List<Long> childIds, Long parentId) {
        List<StoreRole> children = storeRoleMapper.selectList(
            new LambdaQueryWrapper<StoreRole>()
                .eq(StoreRole::getParentId, parentId)
        );

        for (StoreRole child : children) {
            childIds.add(child.getRoleId());
            getChildRoleIdsRecursive(childIds, child.getRoleId());
        }
    }

    /**
     * 构建JsTree格式的JSON
     */
    private String buildJsTreeJson(List<StoreAccess> accesses, List<Long> assignedAccessIds) {
        List<Map<String, Object>> treeData = new ArrayList<>();
        Map<Long, List<StoreAccess>> accessMap = accesses.stream()
            .collect(Collectors.groupingBy(StoreAccess::getParentId));

        buildJsTreeRecursive(treeData, accessMap, 0L, assignedAccessIds);

        // 转换为JSON字符串
        try {
            return com.alibaba.fastjson.JSON.toJSONString(treeData);
        } catch (Exception e) {
            log.error("构建JsTree JSON失败", e);
            return "[]";
        }
    }

    /**
     * 递归构建JsTree数据
     */
    private void buildJsTreeRecursive(List<Map<String, Object>> treeData,
                                    Map<Long, List<StoreAccess>> accessMap,
                                    Long parentId, List<Long> assignedAccessIds) {
        List<StoreAccess> children = accessMap.get(parentId);
        if (CollectionUtils.isEmpty(children)) {
            return;
        }

        for (StoreAccess access : children) {
            Map<String, Object> node = new HashMap<>();
            node.put("id", access.getAccessId());
            node.put("parent", access.getParentId() > 0 ? access.getParentId() : "#");
            node.put("text", access.getName());

            // 设置选中状态
            if (assignedAccessIds != null && assignedAccessIds.contains(access.getAccessId())) {
                Map<String, Object> state = new HashMap<>();
                // 只有叶子节点才设置为选中状态
                List<StoreAccess> subAccess = accessMap.get(access.getAccessId());
                if (CollectionUtils.isEmpty(subAccess)) {
                    state.put("selected", true);
                }
                node.put("state", state);
            }

            treeData.add(node);

            // 递归处理子权限
            buildJsTreeRecursive(treeData, accessMap, access.getAccessId(), assignedAccessIds);
        }
    }

    /**
     * 获取顶级权限列表（parent_id=0）
     */
    private List<StoreAccess> getTopLevelAccess() {
        return storeAccessMapper.selectList(
            new LambdaQueryWrapper<StoreAccess>()
                .eq(StoreAccess::getParentId, 0)
                .orderByAsc(StoreAccess::getSort)
                .orderByAsc(StoreAccess::getAccessId)
        );
    }

    /**
     * 格式化顶级权限数据
     */
    private List<StoreAccessVo> formatTopLevelAccessData(List<StoreAccess> accesses) {
        return accesses.stream()
            .map(access -> {
                StoreAccessVo vo = new StoreAccessVo();
                vo.setAccessId(access.getAccessId());
                vo.setName(access.getName());
                vo.setParentId(access.getParentId());
                vo.setSort(access.getSort());
                vo.setCreateTime(access.getCreateTime());
                vo.setUpdateTime(access.getUpdateTime());
                vo.setDeep(1);
                vo.setNameH1(access.getName());

                // 检查是否有子权限
                List<StoreAccess> subAccess = storeAccessMapper.selectList(
                    new LambdaQueryWrapper<StoreAccess>()
                        .eq(StoreAccess::getParentId, access.getAccessId())
                );
                vo.setHasChildren(!CollectionUtils.isEmpty(subAccess));

                return vo;
            })
            .collect(Collectors.toList());
    }

    /**
     * 获取当前小程序ID
     */
    private Long getCurrentWxappId() {
        // 这里应该从当前登录用户或配置中获取小程序ID
        // 暂时返回默认值
        return 1L;
    }
}
